﻿using Atlanchim.Crm.Mui.Commands;
using Atlanchim.Crm.Mui.Helpers;
using FirstFloor.ModernUI.Windows.Controls;
using Lmondeil.Crm.EF;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Validation;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;

namespace Atlanchim.Crm.Mui.Pages
{
    public abstract class AbstractPageEditModel : INotifyPropertyChanged, IDisposable
    {
        public string Complement { get; set; }

        /// <summary>
        /// Commande de sauvegarde
        /// </summary>
        public ICommand SaveCommand { get; set; }

        /// <summary>
        /// Commande d'annulation
        /// </summary>
        public ICommand CancelCommand { get; set; }

        /// <summary>
        /// Détermine si la navigation en quittant cette page est autorisée
        /// </summary>
        public bool CanNavigate { get; set; }

        /// <summary>
        /// Contexte de persistence
        /// </summary>
        protected CrmContext _pageContext;

        //---------------------------------------------------------------------------------------------------------------------------------------
        #region Chargement

        protected string _fragment = string.Empty;
        /// <summary>
        /// Paramètre passé à la page via l'url
        /// </summary>
        public string Fragment { 
            get {return this._fragment;}
            set
            {
                this._fragment = value;

                if (!string.IsNullOrEmpty(this._fragment))
                {
                    this.DicFragments = FragmentHelper.Split(this._fragment);
                }
            }
        }

        public Dictionary<string, string> DicFragments { get; set; }

        /// <summary>
        /// Methode de chargement
        /// </summary>
        public void Load()
        {
            // Initialisation du contexte
            this._pageContext = new CrmContext();

            // Chargement de l'entité
            this.InnerLoad();

            // Interdiction de quitter la page sans confirmation dès lors que l'entité est chargée
            this.CanNavigate = false;

            // Rattachement des commandes
            if (this.SaveCommand == null)
            {
                this.SaveCommand = new CrmSaveCommand();
            }
            if (this.CancelCommand == null)
            {
                this.CancelCommand = new CrmCancelCommand();
            }
        }

        /// <summary>
        /// Méthode de chargement de l'entité à surcharger
        /// </summary>
        public abstract void InnerLoad();

        #endregion Chargement
        //---------------------------------------------------------------------------------------------------------------------------------------


        //---------------------------------------------------------------------------------------------------------------------------------------
        #region Persistence
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool Quit()
        {
            // Question
            MessageBoxResult bufferAnwser = MessageBox.Show(
                "Voulez-vous enregistrer les modifications",
                "Confirmation",
                MessageBoxButton.YesNoCancel,
                MessageBoxImage.Question,
                MessageBoxResult.Cancel);

            // Résultat
            switch (bufferAnwser)
            {
                case MessageBoxResult.No:
                    this.DontSave();
                   break;
                case MessageBoxResult.Yes:
                    this.Save();
                    break;
                default:
                    break;
            }

            // Retour de fonction
            return this.CanNavigate;
        }

        /// <summary>
        /// Enregistrement des modifications
        /// </summary>
        public void Save()
        {
            try
            {
                this._pageContext.SaveChanges();
                this.CanNavigate = true;
            }
            catch (DbUpdateException excUpdate)
            {
                this.CanNavigate = false;
                string message = "Une erreur est survenue lors de la validation des données à enregistrer.";
                ModernDialog.ShowMessage(message, "Erreur(Update)", MessageBoxButton.OK);
            }
            catch (DbEntityValidationException excValidate)
            {
                this.CanNavigate = false;
                string message = PersistenceErrorHelper.GetEntityValidationErrorMessages(excValidate);
                ModernDialog.ShowMessage(message, "Erreur(Validate)", MessageBoxButton.OK);
            }
            catch (Exception exc)
            {
                this.CanNavigate = false;
                string message = string.Format("Une erreur est survenue lors de l'enregistrement des données : {0}.", exc.Message);
                ModernDialog.ShowMessage(message, "Erreur", MessageBoxButton.OK);
            }

            this.Dispose();
        }

        /// <summary>
        /// Sortie sans enregistrement
        /// </summary>
        public void DontSave()
        {
            this.CanNavigate = true;
            this.Dispose();
        }

        /// <summary>
        /// Retourne à la page précédente
        /// </summary>
        public void NavigateBack()
        {
            TopNavigationHelper.NavigateBackTopFrame();
        }
        #endregion Persistence
        //---------------------------------------------------------------------------------------------------------------------------------------


        //---------------------------------------------------------------------------------------------------------------------------------------
        #region INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion INotifyPropertyChanged
        //---------------------------------------------------------------------------------------------------------------------------------------

        public void Dispose()
        {
            //Libération du contexte de persistence
            if (_pageContext != null)
            {
                _pageContext.Dispose();
                _pageContext = null;
            }
        }
    }

    public class CrmSaveCommand : ICommand
    {
        public bool CanExecute(object parameter)
        {
            // return (parameter is AbstractPageEditModel);
            return true;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            AbstractPageEditModel model = parameter as AbstractPageEditModel;
            model.Save();
            if (model.CanNavigate)
            {
                TopNavigationHelper.NavigateBackTopFrame();
            }
        }
    }

    public class CrmCancelCommand : ICommand
    {
        public bool CanExecute(object parameter)
        {
            return true;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            //AbstractPageEditModel model = parameter as AbstractPageEditModel;
            TopNavigationHelper.NavigateBackTopFrame();
        }
    }
}
